#pragma once

using namespace System;

#include "AP_AtomExtracts.h"

namespace m4aSharp
{
public enum TrackType 
{
	Unkown = 0,
	Video = 2,
	Audio = 4,
	DrmProtected = 8,
	Other = 16
};

public enum CodecType {
	MP4V = 65,
	AVC1 = 66,
	S_AMR = 67,
	S263 = 68
};

public ref class TrackData
{
public:
	property TrackType TypeOfTrack
	{
		TrackType get()
		{
			return (TrackType)type_of_track;
		}
	}
	property bool IsProtected
	{
		bool get()
		{
			return (TypeOfTrack & DrmProtected) == DrmProtected;
		}
	}
	property bool HasAudio
	{
		bool get()
		{
			return (TypeOfTrack & Audio) == Audio;
		}
	}
	property bool HasVideo
	{
		bool get()
		{
			return (TypeOfTrack & Video) == Video;
		}
	}

	property	DateTime CreationTime
	{
		DateTime get()
		{
			DateTime^ d = gcnew DateTime(1904, 1, 1);
			return d->Add(TimeSpan::FromSeconds(creation_time));
		}
	}
	property	DateTime ModifiedTime
	{
		DateTime get()
		{
			DateTime^ d = gcnew DateTime(1904, 1, 1);
			return d->Add(TimeSpan::FromSeconds(modified_time));
		}
	}

	property	UInt32 Duration
	{
		UInt32 get()
		{
			return duration;
		}
	}
	property	bool Enabled
	{
		bool get()
		{
			return track_enabled;
		}
	}
	property	String^ Lang
	{
		String^ get()
		{
			return unpacked_lang;
		}
	}
	property	String^ HdlrName
	{
		String^ get()
		{
			return track_hdlr_name;
		}
	}
	property	String^ EncoderName
	{
		String^ get()
		{
			return  encoder_name;
		}
	}
	property	CodecType Codec
	{
		CodecType get()
		{
			return (CodecType)track_type;
		}
	}
	property	UInt32 CodecCode
	{
		UInt32 get()
		{
			return track_codec;
		}
	}
	property	UInt32 ProtectedCodec
	{
		UInt32 get()
		{
			return protected_codec;
		}
	}
	property	bool ContainsEsds
	{
		bool get()
		{
			return contains_esds;
		}
	}
	property	UInt32 Section3Length
	{
		UInt32 get()
		{
			return section3_length;
		}
	}
	property	UInt32 Section4Length
	{
		UInt32 get()
		{
			return section4_length;
		}
	}
	property	Byte TypeIndication
	{
		Byte get()
		{
			return ObjectTypeIndication;
		}
	}
	property bool IsVBR
	{
		bool get()
		{
			return avg_bitrate != max_bitrate;
		}
	}

	property	UInt32 MaxBitRate
	{
		UInt32 get()
		{
			return max_bitrate;
		}
	}

	property	UInt32 AvgBitRate
	{
		UInt32 get()
		{
			return avg_bitrate;
		}
	}
	property	UInt32 Section5Length
	{
		UInt32 get()
		{
			return section5_length;
		}
	}
	property	Byte DescriptorObjectTypeID
	{
		Byte get()
		{
			return descriptor_object_typeID;
		}
	}
	property	UInt16 Channels
	{
		UInt16 get()
		{
			return channels;
		}
	}

	property	Byte m4vProfile
	{
		Byte get()
		{
			return m4v_profile;
		}
	}
	property	Byte AvcVersion
	{
		Byte get()
		{
			return avc_version;
		}
	}
	property	Byte Profile
	{
		Byte get()
		{
			return  profile;
		}
	}

	property	Byte Level
	{
		Byte get()
		{
			return level;
		}
	}
	property	UInt16 VideoHeight
	{
		UInt16 get()
		{
			return video_height;
		}
	}
	property	UInt16 VideoWidth
	{
		UInt16 get()
		{
			return video_width;
		}
	}
	property	UInt32 MacroBlocks
	{
		UInt32 get()
		{
			return macroblocks;
		}
	}
	property	UInt64 SampleAggregate
	{
		UInt64 get()
		{
			return sample_aggregate;
		}
	}
	property	UInt16 AmrModes
	{
		UInt16 get()
		{
			return amr_modes;
		}
	}

internal:
	TrackData(TrackInfo*);

	UInt32 creation_time;
	UInt32 modified_time;
	UInt32 duration;
	bool track_enabled;
	String^ unpacked_lang;
	String^ track_hdlr_name;
	String^ encoder_name;
	
	UInt32 track_type;
	UInt32 track_codec;
	UInt32 protected_codec;
	
	bool contains_esds;
	
	UInt32 section3_length;
	UInt32 section4_length;
	Byte ObjectTypeIndication;
	UInt32 max_bitrate;
	UInt32 avg_bitrate;
	UInt32 section5_length;
	Byte descriptor_object_typeID;
	UInt16 channels;

	//specifics
	Byte m4v_profile;
	Byte avc_version;
	Byte profile;
	Byte level;
	UInt16 video_height;
	UInt16 video_width;
	UInt32 macroblocks;
	UInt64 sample_aggregate;
	UInt16 amr_modes;
	
	Byte type_of_track;
};
}
